<?php

declare(strict_types=1);


namespace App\CustHub\Controller;

use App\Common\Constants\ErrorCode;
use App\CustHub\Annotation\ApiAuth;
use App\CustHub\Annotation\ChPermission;
use App\CustHub\Annotation\VerifySignature;
use App\CustHub\Constants\OperatorLogConstants;
use App\CustHub\Constants\RobotApplyConstants;
use App\CustHub\Constants\SendConfigConstants;
use App\CustHub\Dto\OperationLogDto;
use App\CustHub\Event\ChOperationLog;
use App\CustHub\Model\ChSop;
use App\CustHub\Model\ChSopSendTask;
use App\CustHub\Model\ChSopSendTaskMain;
use App\CustHub\Model\ChSopSubTask;
use App\CustHub\Model\ChSopTemplate;
use App\CustHub\Service\ChCrowSendingService;
use App\CustHub\Service\ChRobotApplyService;
use App\CustHub\Service\ChSendConfigService;
use App\CustHub\Service\ChSopService;
use App\Exception\BusinessException;
use Hyperf\DbConnection\Db;
use Hyperf\HttpServer\Annotation\Controller;
use Hyperf\HttpServer\Annotation\PostMapping;
use App\CustHub\Service\ChUserService;
use Hyperf\Di\Annotation\Inject;

#[Controller(prefix: 'ch/sop'), ApiAuth, VerifySignature]
class SopController extends BaseController
{
    #[Inject]
    protected ChUserService $service;

    #[Inject]
    protected ChSendConfigService $sendService;

    #[Inject]
    protected ChSopService $chSopService;

    #[Inject]
    protected ChRobotApplyService $applyService;

    #[Inject]
    protected ChCrowSendingService $crowSendService;

    protected $templateTotal=1000;

    /**
     * 添加模板
     * @return \Psr\Http\Message\ResponseInterface
     * @throws \Psr\Container\ContainerExceptionInterface
     * @throws \Psr\Container\NotFoundExceptionInterface
     */
    #[PostMapping('template/add'), ChPermission('ch:sop:template:add')]
    public function addTemplate()
    {
        $this->validateParam([
            'title' => 'required',
            'is_personal' => 'required',
            'template_type' => 'required',
            'plan' => 'required',
        ]);
        $uid = $this->request->input('uid');
        $mainUid = $this->request->input('main_uid');
        $params = $this->request->all();
        if($params['is_personal']){
            $total = ChSopTemplate::query()->where('uid', $uid)->where('is_personal', 1)->count();
        }else{
            $total = ChSopTemplate::query()->where('main_uid', $mainUid)->where('is_personal', 0)->count();
        }
        if($total>$this->templateTotal){
            $this->error('最大模板数量'.$this->templateTotal.'个');
        }
        $res = ChSopTemplate::saveTemplate($uid, $mainUid, $params);
        return $this->success('添加成功', $res);
    }


    #[PostMapping('template/edit'), ChPermission('ch:sop:template:edit')]
    public function editTemplate()
    {
        $this->validateParam([
            'title' => 'required',
            'is_personal' => 'required',
            'plan' => 'required',
            'id' => 'required',
        ]);
        Db::beginTransaction();
        try {
            $uid = $this->request->input('uid');
            $id = $this->request->input('id');
            $mainUid = $this->request->input('main_uid');
            $params = $this->request->all();
            $template=ChSopTemplate::saveTemplate($uid, $mainUid, $params, $id);
            $this->chSopService->afterEditTemplate($template);
            Db::commit();
            return $this->success('添加成功');
        } catch (\Exception $e) {
            Db::rollBack();
            return $this->error($e->getMessage());
        }
    }

    #[PostMapping('template/delete'), ChPermission('ch:sop:template:delete')]
    public function deleteTemplate()
    {
        $this->validateParam([
            'id' => 'required',
        ]);
        $uid = $this->request->input('uid');
        $id = $this->request->input('id');
        $params = $this->request->all();
        $res = ChSopTemplate::query()->where('id', $id)->delete();
        return $this->success('删除成功');
    }

    #[PostMapping('template/copy'), ChPermission('ch:sop:template:copy')]
    public function copyTemplate()
    {
        $this->validateParam([
            'is_personal' => 'required',
            'id' => 'required',
        ]);
        $uid = $this->request->input('uid');
        $id = $this->request->input('id');
        $info = ChSopTemplate::query()->where('id', $id)->first();
        if (empty($info)) return $this->error('数据不存在', ErrorCode::NOT_ISSET);
        $mainUid = $this->request->input('main_uid');
        $params = [];
        $params['is_personal'] = $this->request->input('is_personal');
        $params['title'] = $info['title'];
        $params['template_type'] = $info->template_type;
        $params['plan'] = $info->plan;
        $params['is_return'] = $info->is_return;
        $params['return_code'] = $info->return_code;
        $params['return_text'] = $info->return_text;
        $res = ChSopTemplate::saveTemplate($uid, $mainUid, $params);
        return $this->success('添加成功', $res);
    }

    #[PostMapping('template/detail'), ChPermission('ch:sop:template:detail')]
    public function templateDetail()
    {
        $this->validateParam([
            'id' => 'required',
        ]);
        $uid = $this->request->input('uid');
        $mainUid = $this->request->input('main_uid');
        $id = $this->request->input('id');
        $res = ChSopTemplate::query()->withTrashed()->where('id', $id)->first();
        return $this->success('获取成功', $res);
    }

    #[PostMapping('template/list'), ChPermission('ch:sop:template:list')]
    public function templateList()
    {
        $this->validateParam([
            'is_personal' => 'required',
        ]);
        $uid = $this->request->input('uid');
        $isPersonal = $this->request->input('is_personal');
        $mainUid = $this->request->input('main_uid');
        $templateType = $this->request->input('template_type');
        $page_size = $this->request->input('page_size', 15);

        if ($isPersonal == 1) {
            $where = [
                ['uid', '=', $uid],
                ['is_personal', '=', 1]
            ];
        } else {
            $where = [
                ['main_uid', '=', $mainUid],
                ['is_personal', '=', 0]
            ];
        }
        if (!empty($templateType)) {
            $where[] = ['template_type', '=', $templateType];
        }
        $page = ChSopTemplate::query()->where($where)->select(['title', 'id', 'created_at', 'updated_at', 'is_return', 'template_type', 'plan'])->paginate((int)$page_size);
        $list = $page->items();
        $total = $page->total();
        $personalTotal = ChSopTemplate::query()->where('uid', $uid)->where('is_personal', 1)->count();
        $corpTotal = ChSopTemplate::query()->where('main_uid', $mainUid)->where('is_personal', 0)->count();
        return $this->success('获取成功', ['list' => $list, 'total' => $total, 'personal_total' => $personalTotal, 'corp_total' => $corpTotal]);
    }


    #[PostMapping('plan/list'), ChPermission('ch:sop:plan:list')]
    public function planList()
    {
        $params=$this->request->all();
        $uid = $this->request->input('uid');
        $mainUid = $this->request->input('main_uid');
        $templateId = $this->request->input('template_id', 0);
        //对象名称
        $keyword = $this->request->input('keyword');
        $is_room = $this->request->input('is_room', 0);
        $has_fail = $this->request->input('has_fail', 0);
        $page_size = $this->request->input('page_size', 15);
        $sop_id = $this->request->input('sop_id');
        $task_main_id = $this->request->input('task_main_id');
        $template_type = $this->request->input('template_type');
        $order = "id desc";
        $where[] = ['uid', '=', $uid];
        //$where[] = ['status', '=', 1];
        $where[] = ['is_room', '=', $is_room];
        if ($sop_id) {
            $where[] = ['sop_id', '=', $sop_id];
        }
        if ($task_main_id) {
            $where[] = ['task_main_id', '=', $task_main_id];
        }
        if ($templateId) {
            $where[] = ['template_id', '=', $templateId];
        }
        if ($keyword) {
            $where[] = ['object_name', '=', $keyword];
        }
        if ($template_type) {
            $where[] = ['template_type', '=', $template_type];
        }
        if ($is_room) {
            $build = ChSopSendTaskMain::query()->with(['room' => function ($q) {
                $q->select('id', 'room_wxid', 'room_name', 'room_member_count', 'room_avatar_url');
            }, 'template' => function ($q) {
                $q->select('id', 'title');
            }]);
        } else {
            $build = ChSopSendTaskMain::query()->with(['contact' => function ($q) {
                $q->select('id', 'user_id', 'nickname', 'is_wechat', 'corp_short_name', 'avatar');
            }, 'template' => function ($q) {
                $q->select('id', 'title');
            }]);
        }
        $build->where($where)->orderByRaw($order);
        if (!empty($params['start_time']) && !empty($params['end_time'])) {
            $build->whereBetween('created_at', [$params['start_time'], $params['end_time']]);
        }
        if (!empty($has_fail)) {
            $build->whereHas('task', function ($q) use ($keyword) {
                $q->where('status', 5);
            });
        }
        $page = $build->paginate((int)$page_size);
        $page->getCollection()->transform(function ($item) {
            $item->process=!empty($item->complate_day)?intval($item->complate_day/$item->day*100):0;
            return $item;
        });
        $data = [
            'items' => $page->items(),
            'pageInfo' => [
                'total' => $page->total(),
                'currentPage' => $page->currentPage(),
                'totalPage' => $page->lastPage(),
            ],
        ];
        return $this->success('获取成功', $data);
    }

    #[PostMapping('cancel'), ChPermission('ch:sop:cancel')]
    public function cancel()
    {
        $uid = $this->request->input('uid');
        $mainUid = $this->request->input('main_uid');
        $id = $this->request->input('id', 0);
        Db::beginTransaction();
        try {
            ChSop::query()->where('id', $id)->update(['status' => 3]);
            ChSopSendTaskMain::query()->where('sop_id', $id)->update(['status' => 2]);
            ChSopSendTask::query()->where('sop_id', $id)->update(['status' => 2]);
            Db::commit();
            return $this->success('操作成功');
        } catch (\Exception $e) {
            Db::rollBack();
            return $this->error($e->getMessage());
        }
    }


    #[PostMapping('plan/cancel'), ChPermission('ch:sop:plan:cancel')]
    public function cancelPlan()
    {
        $uid = $this->request->input('uid');
        $mainUid = $this->request->input('main_uid');
        $id = $this->request->input('id', 0);
        Db::beginTransaction();
        try {
            ChSopSendTaskMain::query()->where('id', $id)->update(['status' => 2]);
            ChSopSendTask::query()->where('task_main_id', $id)->update(['status' => 2]);
            Db::commit();
            return $this->success('操作成功');
        } catch (\Exception $e) {
            Db::rollBack();
            return $this->error($e->getMessage());
        }
    }


    #[PostMapping('plan/detail'), ChPermission('ch:sop:plan:detail')]
    public function cancelDetail()
    {
        $uid = $this->request->input('uid');
        $mainUid = $this->request->input('main_uid');
        $id = $this->request->input('id', 0);
        //查看计划任务详情
        $data = ChSopSendTask::query()->where('task_main_id', $id)->orderBy('day', 'asc')->get();
        return $this->success($data);
    }

    /**
     * 批量设置下发机器人状态
     * @return \Psr\Http\Message\ResponseInterface
     * @throws \Psr\Container\ContainerExceptionInterface
     * @throws \Psr\Container\NotFoundExceptionInterface
     */
    #[PostMapping('set_robot_batch'), ChPermission('ch:sop:set_field_batch')]
    public function setFieldBatch()
    {
        $this->validateParam([
            'id' => 'required',
            'type' => 'required',
            'corp_id' => 'required',
            'robot_ids' => 'required',
        ]);
        //type 1批量取消  2批量开启  3批量关闭
        $uid = $this->request->input('uid');
        $id = $this->request->input('id');
        $type = $this->request->input('type');
        $corpId = $this->request->input('corp_id');
        $robotIds = $this->request->input('robot_ids');
        $robotIds = is_array($robotIds) ? $robotIds : json_decode($robotIds, true);
        if ($type == 1) {
            $this->applyService->robotBatchCancelApply($corpId, RobotApplyConstants::SOP, $id, $robotIds);
        }
        if ($type == 2) {
            $this->applyService->robotBatchOpenApply($corpId, RobotApplyConstants::SOP, $id, $robotIds);
        }
        if ($type == 3) {
            $this->applyService->robotBatchCloseApply($corpId, RobotApplyConstants::SOP, $id, $robotIds);
        }
        return $this->success('操作成功');
    }

    #[PostMapping('plan/log'), ChPermission('ch:sop:plan:log')]
    public function planLog()
    {

        $uid = $this->request->input('uid');
        $mainUid = $this->request->input('main_uid');
        $templateId = $this->request->input('template_id', 0);
        //对象名称
        $keyword = $this->request->input('keyword');
        $is_room = $this->request->input('is_room', 0);
        $has_fail = $this->request->input('has_fail', 0);
        $page_size = $this->request->input('page_size', 15);
        $sop_id = $this->request->input('sop_id');
        $task_main_id = $this->request->input('task_main_id');
        $template_type = $this->request->input('template_type');
        $order = "id desc";
        $where[] = ['uid', '=', $uid];
        $where[] = ['status', '=', 2];
        $where[] = ['is_room', '=', $is_room];
        if ($sop_id) {
            $where[] = ['sop_id', '=', $sop_id];
        }
        if ($task_main_id) {
            $where[] = ['task_main_id', '=', $task_main_id];
        }
        if ($templateId) {
            $where[] = ['template_id', '=', $templateId];
        }
        if ($keyword) {
            $where[] = ['object_name', '=', $keyword];
        }
        if ($template_type) {
            $where[] = ['template_type', '=', $template_type];
        }
        if ($is_room) {
            $build = ChSopSendTaskMain::query()->with(['room' => function ($q) {
                $q->select('id', 'room_wxid', 'room_name', 'room_member_count', 'room_avatar_url');
            }, 'template' => function ($q) {
                $q->select('id', 'title');
            }]);
        } else {
            $build = ChSopSendTaskMain::query()->with(['contact' => function ($q) {
                $q->select('id', 'user_id', 'nickname', 'is_wechat', 'corp_short_name', 'avatar');
            }, 'template' => function ($q) {
                $q->select('id', 'title');
            }]);
        }
        $build->where($where)->whereIn('status', [1, 3])->orderByRaw($order);
        if (!empty($params['start_time']) && !empty($params['end_time'])) {
            $build->whereBetween('created_at', [$params['start_time'], $params['end_time']]);
        }
        if (!empty($has_fail)) {
            $build->whereHas('task', function ($q) use ($keyword) {
                $q->where('status', 5);
            });
        }
        $page = $build->paginate((int)$page_size);
        $page->getCollection()->transform(function ($item) {
            $item->process=!empty($item->complate_day)?intval($item->complate_day/$item->day):0;
            return $item;
        });
        $data = [
            'items' => $page->items(),
            'pageInfo' => [
                'total' => $page->total(),
                'currentPage' => $page->currentPage(),
                'totalPage' => $page->lastPage(),
            ],
        ];
        return $this->success('获取成功', $data);
    }


    #[PostMapping('list'), ChPermission('ch:sop:list')]
    public function list()
    {

        $params=$this->request->all();
        $uid = $this->request->input('uid');
        $mainUid = $this->request->input('main_uid');
        $templateType = $this->request->input('template_type');
        $keyword = $this->request->input('keyword');
        $page_size = $this->request->input('page_size', 15);

        $where[] = ['uid', '=', $uid];
        if (!empty($templateType)) {
            $where[] = ['template_type', '=', $templateType];
        }

        $build = ChSop::query()->with(['user' => function ($q) {
            $q->select('id', 'nickname');
        }, 'template' => function ($q) {
            $q->select('id', 'title');
        }])->where($where)
            ->orderBy('id', 'desc')
            ->select(['id', 'main_uid', 'uid', 'corp_id', 'template_id', 'title', 'template_type', 'status', 'open_out_tag', 'auto_stop', 'is_track', 'tirgger_type', 'send_type', 'crowd_ids', 'custom_ids', 'start_day', 'created_at', 'updated_at', 'condition_conf', 'trigger_condition', 'out_tag', 'trigger_tag']);
        if (!empty($params['start_time']) && !empty($params['end_time'])) {
            $build->whereBetween('created_at', [$params['start_time'], $params['end_time']]);
        }
        if (!empty($keyword)) {
            $build->whereHas('template', function ($q) use ($keyword) {
                $q->where('title', 'like', "%{$keyword}%");
            });
        }
        $page = $build->paginate((int)$page_size);
        foreach ($page as &$item) {
            //$item['robots'] = $this -> applyService -> getApplyRobotsInfo(RobotApplyConstants::SOP,$item['id']);
            $item = $this->chSopService->formatTriggerCondition($item);
        }
        unset($item);
        $data = [
            'items' => $page->items(),
            'pageInfo' => [
                'total' => $page->total(),
                'currentPage' => $page->currentPage(),
                'totalPage' => $page->lastPage(),
            ],
        ];
        return $this->success('获取成功', $data);
    }


    #[PostMapping('robot/apply_list'), ChPermission('ch:sop:robot:list')]
    public function robotApplyList()
    {
        $uid = $this->request->input('uid');
        $mainUid = $this->request->input('main_uid');
        $id = $this->request->input('id');

        $data = $this->applyService->getApplyRobotsInfo(RobotApplyConstants::SOP, $id);
        return $this->success('获取成功', $data);
    }


    #[PostMapping('robot/list'), ChPermission('ch:sop:robot:list')]
    public function robotList()
    {

        $uid = $this->request->input('uid');
        $mainUid = $this->request->input('main_uid');
        $id = $this->request->input('id');
        $keyword = $this->request->input('keyword');
        $page_size = $this->request->input('page_size', 15);

        $where[] = ['uid', '=', $uid];
        $where[] = ['sop_id', '=', $id];


        $build = ChSopSubTask::query()->with(['robot' => function ($q) {
            $q->select(['id', 'nickname', 'avatar', 'user_id', 'login_status', 'corp_name']);
        }, 'template' => function ($q) {
            $q->select(['id', 'title']);
        }])->where($where);
        $page = $build->paginate((int)$page_size);
        $data = [
            'items' => $page->items(),
            'pageInfo' => [
                'total' => $page->total(),
                'currentPage' => $page->currentPage(),
                'totalPage' => $page->lastPage(),
            ],
        ];
        return $this->success('获取成功', $data);
    }

    #[PostMapping('add'), ChPermission('ch:sop:add')]
    public function add()
    {
        $this->validateParam([
            'plan' => 'required',
            'template_id' => 'required',
            //'corp_id' => 'required',
        ]);
        $uid = $this->request->input('uid');
        $mainUid = $this->request->input('main_uid');
        $templateType = $this->request->input('template_type');
        //$corpId = $this->request->input('corp_id');
        $startDay = $this->request->input('start_day', 0);
        $params = $this->request->all();
        Db::beginTransaction();
        try {
            $res = ChSop::saveSop($uid, $mainUid, $params, 0, $startDay);
            if ($res->template_type == 1) {
                //标准模板直接手动创建计划任务
                $robotIds = !is_array($params['robot_ids']) ? json_decode($params['robot_ids'], true) : $params['robot_ids'];
                $this->applyService->batchApply(0, RobotApplyConstants::SOP, [$res->id], $robotIds);
                //创建发送对象
                $this->chSopService->triggerStandardSop($res, $res->template_type,$robotIds, $startDay);
            }
            //记录日志
            event((new ChOperationLog(
                (new OperationLogDto())
                    ->setUid($uid)
                    ->setMainUid($mainUid)
                    ->setSchemeId($res->id)
                    ->setName($params['title'])
                    ->setContent('添加sop任务')
                    ->setType(OperatorLogConstants::SOP)
            )));
            Db::commit();
            return $this->success('添加成功', $res);
        } catch (\Throwable $ex) {
            Db::rollBack();
            throw new BusinessException((int)$ex->getCode(), $ex->getMessage());
        }

    }


    #[PostMapping('edit'), ChPermission('ch:sop:edit')]
    public function edit()
    {
        $this->validateParam([
            'plan' => 'required',
            'template_id' => 'required',
            'id' => 'required',
        ]);
        $uid = $this->request->input('uid');
        $mainUid = $this->request->input('main_uid');
        $id = $this->request->input('id');
        $params = $this->request->all();
        $sop = ChSop::saveSop($uid, $mainUid, $params, $id);
        //更新主任务
        $data=[
            'is_track'=>$sop -> is_track,
            'track_limit'=>$sop -> track_limit,
        ];
        ChSopSendTaskMain::query()->where('sop_id',$sop->id)->update($data);
        //记录日志
        event((new ChOperationLog(
            (new OperationLogDto())
                ->setUid($uid)
                ->setMainUid($mainUid)
                ->setSchemeId($sop->id)
                ->setName($params['title'])
                ->setContent('编辑sop任务')
                ->setType(OperatorLogConstants::SOP)
        )));
        return $this->success('添加成功', $sop);
    }

    #[PostMapping('detail'), ChPermission('ch:sop:detail')]
    public function detail()
    {
        $this->validateParam([
            'id' => 'required',
        ]);
        $uid = $this->request->input('uid');
        $mainUid = $this->request->input('main_uid');
        $id = $this->request->input('id');
        $params = $this->request->all();
        $res = ChSop::query()->with('template')->where('id', $id)->first();
        !empty($res['condition_conf']) && $res['condition_conf'] = $this->crowSendService->formatConditionToText2($res['condition_conf']);
        $res = $this->chSopService->formatTriggerCondition($res);
        return $this->success('获取成功', $res);
    }

    #[PostMapping('delete'), ChPermission('ch:sop:delete')]
    public function delete()
    {
        $this->validateParam([
            'id' => 'required',
        ]);
        $uid = $this->request->input('uid');
        $mainUid = $this->request->input('main_uid');
        $id = $this->request->input('id');
        $params = $this->request->all();
        $res = ChSop::query()->where('id', $id)->delete();
        return $this->success('操作成功');
    }


    #[PostMapping('bind'), ChPermission('ch:sop:detail:bind')]
    public function bindRobot()
    {
        $this->validateParam([
            'sop_ids' => 'required',
            'robot_ids' => 'required',
            'corp_id' => 'required'
        ]);
        $sopIds = $this->request->input('sop_ids');
        $robotUserIds = $this->request->input('robot_ids');
        $corpId = $this->request->input('corp_id');
        if (!is_array($sopIds)) {
            $sopIds = json_decode($sopIds, true);
        }

        if (!is_array($robotUserIds)) {
            $robotUserIds = json_decode($robotUserIds, true);
        }
        $this->applyService->batchApply($corpId, RobotApplyConstants::SOP, $sopIds, $robotUserIds);
        return $this->success('绑定成功');
    }


    #[PostMapping('apply_log'), ChPermission('ch:sop:apply_log')]
    public function getApplyLog()
    {
        $this->validateParam([
            'query_type' => 'required',
            'corp_id' => 'required'
        ]);
        $queryType = $this->request->input('query_type');
        $corpId = $this->request->input('corp_id');
        $id = $this->request->input('id');

        $res = $this->applyService->getApplyLog(ChSop::getModel()->getTable(), RobotApplyConstants::SOP, $corpId, $queryType,$id);
        return $this->success($res);
    }

    #[PostMapping('system/list'), ChPermission('ch:sop:system:list')]
    public function systemList()
    {
        $data = $this->request->all();
        $data['type'] = SendConfigConstants::SOP;
        $list = $this->sendService->getConfigList($data);
        return $this->success('获取成功', $list);
    }

    #[PostMapping('system/detail'), ChPermission('ch:sop:system:detail')]
    public function systemDetail()
    {
        $this->validateParam([
            'robot_id' => 'required',
        ]);

        $mainUid = $this->request->input('main_uid');
        $uid = $this->request->input('uid');
        $robot_id = $this->request->input('robot_id');
        $detail = $this->sendService->getConfig(SendConfigConstants::SOP, $uid, $robot_id);
        return $this->success('获取成功', $detail);
    }


    /**
     * 获取sop统计数据
     */
    #[PostMapping('statistics/list'), ChPermission('ch:sop:statistics:list')]
    public function statisticsList()
    {
        $mainUid = $this->request->input('main_uid');
        $uid = $this->request->input('uid');
        return $this->success($this->chSopService->getStatisticsList($this->request->all()));
    }



    /**
     * 获取sop统计数据
     */
    #[PostMapping('statistics/dayList'), ChPermission('ch:sop:statistics:list')]
    public function statisticsListBuyDay()
    {
        $mainUid = $this->request->input('main_uid');
        $uid = $this->request->input('uid');
        return $this->success($this->chSopService->getStatisticsListByDay($this->request->all()));
    }


}